//
//  BaseHttpRequest.m
//  GSDache
//
//  Created by tanyin on 16/11/28.
//  Copyright © 2016年 tanyin. All rights reserved.
//

#import "BaseHttpRequest.h"
#import "AKAFManager.h"
#import "BaseHttpRequestModel.h"

@interface BaseHttpRequest ()

/*
 * AFNetWorking 新建单例请求 以免内存 遗漏
 */
//@property(weak, nonatomic) AKAFManager *m_sessionManager;
@property(weak, nonatomic) AFHTTPSessionManager *m_sessionManager;


@end

@implementation BaseHttpRequest

-(instancetype)init{
    self = [super init];
    if (self) {
//        _m_sessionManager = [AKAFManager getManager];
        _m_sessionManager = [AFHTTPSessionManager manager];
        _m_sessionManager.requestSerializer.timeoutInterval = 15.f;
        //忽略证书
        _m_sessionManager.securityPolicy.allowInvalidCertificates = YES;
        _m_sessionManager.securityPolicy.validatesDomainName = NO;
        
        //
        _m_sessionManager.responseSerializer.acceptableContentTypes = [self acceptableContentTypes];
    }
    return self;
}

- (NSSet <NSString *> *)acceptableContentTypes {
    return [NSSet setWithObjects:@"application/json",
                                 @"text/html",
                                 @"text/plain",
                                 @"text/javascript",
                                 @"text/xml",
                                 @"text/json",nil];
}

- (AFHTTPSessionManager *)session {
    return _m_sessionManager;
}

-(NSURLSessionDataTask *)post:(BaseHttpRequestModel *)uploadDataModel
                      success:(success)success
                      failure:(failure)failure{
    
    [self setHeader:uploadDataModel];
    NSURLSessionDataTask *task = [_m_sessionManager POST:uploadDataModel.absoluteUrl parameters:[uploadDataModel yy_modelToJSONObject] progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (success) {
            success(task,responseObject);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        if (failure) {
            failure(task,error);
        }
    }];
    return task;
}

-(void)postFile:(BaseHttpRequestModel *)uploadDataModel
       progress:(progress)progress
        success:(success)success
        failure:(failure)failure{
    
    [self setHeader:uploadDataModel];
    // AFNetWorking bug,the iOS 7.0 version, post function header content_type is 0.
    if (SYSTEM_VERSION > 7.f) {
        
        WEAK_SELF
        [_m_sessionManager POST:uploadDataModel.absoluteUrl parameters:[uploadDataModel yy_modelToJSONObject] constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
            
            [wself writeUploadDataToFormData:formData uploadDataModel:uploadDataModel];
        } progress:^(NSProgress * _Nonnull uploadProgress) {
            
            if (progress) {
                progress(uploadProgress);
            }
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            if (success) {
                success(task,responseObject);
            }
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
            if (failure) {
                failure(task,error);
            }
        }];
    }else{
        
        [self iOS7_postFile:uploadDataModel progress:progress success:success failure:failure];
    }
}

-(NSURLSessionDataTask *)put:(BaseHttpRequestModel *)uploadDataModel
                     success:(success)success
                     failure:(failure)failure{
    
    [self setHeader:uploadDataModel];
    NSURLSessionDataTask *task = [_m_sessionManager PUT:uploadDataModel.absoluteUrl parameters:[uploadDataModel yy_modelToJSONObject] success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        if (success) {
            success(task, responseObject);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        if (failure) {
            failure(task, error);
        }
    }];
    return task;
}

-(NSURLSessionDataTask *)delete:(BaseHttpRequestModel *)uploadDataModel
                        success:(success)success
                        failure:(failure)failure{
    
    [self setHeader:uploadDataModel];
    NSURLSessionDataTask *task = [_m_sessionManager DELETE:uploadDataModel.absoluteUrl parameters:[uploadDataModel yy_modelToJSONObject] success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        if (success) {
            
            success(task,responseObject);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        if (failure) {
            failure(task,error);
        }
    }];
    return task;
}

-(NSURLSessionDataTask *)get:(BaseHttpRequestModel *)uploadDataModel
                     success:(success)success
                     failure:(failure)failure{
    
    [self setHeader:uploadDataModel];
    NSURLSessionDataTask *task = [_m_sessionManager GET:uploadDataModel.absoluteUrl parameters:[uploadDataModel yy_modelToJSONObject] progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (success) {
            success(task,responseObject);
        }
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        if (failure) {
            failure(task,error);
        }
    }];
    return task;
}

#pragma mark - _private method

-(void)setHeader:(BaseHttpRequestModel *)uploadDataModel{
    
    WEAK_SELF
    NSDictionary *dic = [uploadDataModel headerParameter];
//    NSLog(@"headerParameter: %@",dic);
    if (dic)
        [dic bk_each:^(id  _Nonnull key, id  _Nonnull obj) {
            
            [wself.m_sessionManager.requestSerializer setValue:obj forHTTPHeaderField:key];
        }];
}

-(void)iOS7_postFile:(BaseHttpRequestModel *)uploadDataModel
            progress:(progress)progress
             success:(success)success
             failure:(failure)failure{
    
    WEAK_SELF
    NSString* tmpFilename = [NSString stringWithFormat:@"%f", [NSDate timeIntervalSinceReferenceDate]];
    NSURL* tmpFileUrl = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:tmpFilename]];
    
    // Create a multipart form request.
    NSMutableURLRequest *multipartRequest = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:[uploadDataModel absoluteUrl] parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        
        [wself writeUploadDataToFormData:formData uploadDataModel:uploadDataModel];
    } error:nil];
    
    // Dump multipart request into the temporary file.
    [[AFHTTPRequestSerializer serializer] requestWithMultipartFormRequest:multipartRequest writingStreamContentsToFile:tmpFileUrl completionHandler:^(NSError * _Nullable error) {
        
        AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
        
        NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:multipartRequest fromFile:tmpFileUrl progress:^(NSProgress * _Nonnull uploadProgress) {
            
            progress(uploadProgress);
        } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
            
            [[NSFileManager defaultManager] removeItemAtURL:tmpFileUrl error:nil];
            if (error) {
                
                failure(nil,error);
            }else{
                
                success(nil, responseObject);
            }
        }];
        [uploadTask resume];
    }];
}

-(void)writeUploadDataToFormData:(id<AFMultipartFormData>)formData uploadDataModel:(BaseHttpRequestModel *)uploadDataModel{
    
    [[uploadDataModel uploadDatas] bk_each:^(NSDictionary *obj) {
        
        NSData *data = obj[@"data"];
        NSString *fileName = obj[@"fileName"];
        NSString *name = obj[@"name"];
        NSString *mimeType = obj[@"mimeType"];
        [formData appendPartWithFileData:data name:name fileName:fileName mimeType:mimeType];
    }];
}



@end
